package net.thxjj.mobileServer.controller.mobile;

import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import lombok.extern.slf4j.Slf4j;
import net.thxjj.mobileServer.controller.base.BaseController;
import net.thxjj.mobileServer.entity.Const;
import net.thxjj.mobileServer.entity.EmailCodeBean;
import net.thxjj.mobileServer.entity.ResponseModel;
import net.thxjj.mobileServer.entity.ResultEnum;
import net.thxjj.mobileServer.service.ISendEmailService;
import net.thxjj.mobileServer.service.IUaaService;
import net.thxjj.mobileServer.util.ParameterMap;
import net.thxjj.mobileServer.util.Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Random;
/**
 * @ClassName:MobileUaaController
 * @Description:TODO
 * @Autor:TracyHenry
 * @Date:2022/12/18 0018
 * @Version:1.0
 **/
@Slf4j
@RestController
@RequestMapping("/uaa")
public class MobileUaaController extends BaseController {
    private static final long TYPE_EMAIL_REGISTER = 1;
    private static final long TYPE_EMAIL_RESET = 2;

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @Autowired
    private IUaaService uaaService;

    @Autowired
    private ISendEmailService sendEmailService;

    /**
     * 获取验证码 的 请求路径
     * @throws Exception
     */
    @RequestMapping("/getKaptcha")
    public void defaultKaptcha() throws Exception {
        byte[] captchaChallengeAsJpeg = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            //生产验证码字符串并保存到session中
            String createText = defaultKaptcha.createText();
            //120秒失效
            this.getSession().invalidate();
            this.getSession().setAttribute("checkCode", createText);
            this.getSession().setMaxInactiveInterval((int)Const.EMAIL_CODE_EXPIRE_TIME);
            //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
            BufferedImage challenge = defaultKaptcha.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
        } catch (IllegalArgumentException e) {
            this.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        //定义response输出类型为image/jpeg类型，使用response输出流输出图片的byte数组
        captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
        this.getResponse().setHeader("Cache-Control", "no-store");
        this.getResponse().setHeader("Pragma", "no-cache");
        this.getResponse().setDateHeader("Expires", 0);
        this.getResponse().setContentType("image/jpeg");
        ServletOutputStream responseOutputStream =
                this.getResponse().getOutputStream();
        responseOutputStream.write(captchaChallengeAsJpeg);
        responseOutputStream.flush();
        responseOutputStream.close();
    }


    /**
     * register
     * @return
     * 发送邮箱验证码功能(图形校验，用于注册和重置密码)
     */
    @RequestMapping(value = "/checkCaptcha",method = RequestMethod.POST)
    @ResponseBody
    public Object checkCaptcha(@RequestBody JSONObject jsonObject){
        String pid = jsonObject.getString("pid");
       String code = jsonObject.getString("code");
       String email = jsonObject.getString("email");
       long type = jsonObject.getLongValue("type");

       String realcode = (String)this.getSession().getAttribute("checkCode");
        if(Tools.isEmpty(code)){
            return ResponseModel.getModel(ResultEnum.CHECK_CODE_IS_EMPTY,null);
        }

        if(!code.equals(realcode)){
            return ResponseModel.getModel(ResultEnum.CHECK_CODE_IS_NOT_MATCH, null);
        }

        if(Tools.isEmpty(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_EMPTY_ERROR,null);
        }

        if(Tools.isEmpty(pid)){
            return ResponseModel.getModel(ResultEnum.PID_EMPTY_ERROR,null);
        }

        if(type!=TYPE_EMAIL_REGISTER && type!=TYPE_EMAIL_RESET){
            return ResponseModel.getModel(ResultEnum.PARAMETER_ERROR,null);
        }

        if(!Tools.isEmail(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_FORMAT_ERROR,null);
        }

        boolean flag = uaaService.isPidExist(pid);
        if(!flag){
            return ResponseModel.getModel(ResultEnum.PID_IS_NOT_EXIST_ERROR,null);
        }

        String sessionId = this.getSession().getId();

        boolean flagMultipleSending = sendEmailService.checkMultipleSending(sessionId);
        if(flagMultipleSending){
            return ResponseModel.getModel(ResultEnum.SEND_MAIL_CODE_MULI_ERROR,null);
        }

        if(uaaService.isUserExist(email,pid) && type==TYPE_EMAIL_REGISTER){
            return ResponseModel.getModel(ResultEnum.USERNAME_IS_EXIST, null);
        }

        if(!uaaService.isUserExist(email,pid)&& type==TYPE_EMAIL_RESET){
            return ResponseModel.getModel(ResultEnum.USER_IS_NOT_EXIST, null);
        }

        this.getSession().setMaxInactiveInterval((int)Const.EMAIL_CODE_EXPIRE_TIME);
        String randomCode = getrandom();
        String ip = this.getParameterMap().getString("rip");
        String session = this.getSession().getId();
        EmailCodeBean emailCodeBean = new EmailCodeBean(session,email,randomCode,pid,System.currentTimeMillis(),type,ip);
        long id = uaaService.insertEmailVerifyCode(emailCodeBean);

        if(id<=0) {
            return ResponseModel.getModel(ResultEnum.FAILED,null);
        }

        if(type==TYPE_EMAIL_REGISTER)
            sendEmailService.sendRegisterVerifyCode(email,randomCode);
        else
            sendEmailService.sendResetVerifyCode(email,randomCode);
        return ResponseModel.getModel(ResultEnum.SUCCESS,null);
    }

    /**
     * register
     * @return
     * 发送邮箱验证码功能(无图形校验,用于注册和重置密码)
     */
    @RequestMapping(value = "/sendVerifyCode",method = RequestMethod.POST)
    @ResponseBody
    public Object sendVerifyCode(@RequestBody JSONObject jsonObject){
        String pid = jsonObject.getString("pid");
        String email = jsonObject.getString("email");
        long type = jsonObject.getLongValue("type");

        if(Tools.isEmpty(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_EMPTY_ERROR,null);
        }

        if(Tools.isEmpty(pid)){
            return ResponseModel.getModel(ResultEnum.PID_EMPTY_ERROR,null);
        }

        if(type!=TYPE_EMAIL_REGISTER && type!=TYPE_EMAIL_RESET){
            return ResponseModel.getModel(ResultEnum.PARAMETER_ERROR,null);
        }

        if(!Tools.isEmail(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_FORMAT_ERROR,null);
        }

        boolean flag = uaaService.isPidExist(pid);
        if(!flag){
            return ResponseModel.getModel(ResultEnum.PID_IS_NOT_EXIST_ERROR,null);
        }

        String sessionId = this.getSession().getId();

        boolean flagMultipleSending = sendEmailService.checkMultipleSending(sessionId);
        if(flagMultipleSending){
            return ResponseModel.getModel(ResultEnum.SEND_MAIL_CODE_MULI_ERROR,null);
        }

        if(uaaService.isUserExist(email,pid) && type==TYPE_EMAIL_REGISTER){
            return ResponseModel.getModel(ResultEnum.USERNAME_IS_EXIST, null);
        }

        if(!uaaService.isUserExist(email,pid)&& type==TYPE_EMAIL_RESET){
            return ResponseModel.getModel(ResultEnum.USER_IS_NOT_EXIST, null);
        }

        this.getSession().setMaxInactiveInterval((int)Const.EMAIL_CODE_EXPIRE_TIME);
        String randomCode = getrandom();
        String ip = this.getParameterMap().getString("rip");
        EmailCodeBean emailCodeBean = new EmailCodeBean(sessionId,email,randomCode,pid,System.currentTimeMillis(),type,ip);
        long id = uaaService.insertEmailVerifyCode(emailCodeBean);

        if(id<=0) {
            return ResponseModel.getModel(ResultEnum.FAILED,null);
        }

        if(type==TYPE_EMAIL_REGISTER)
        sendEmailService.sendRegisterVerifyCode(email,randomCode);
        else
        sendEmailService.sendResetVerifyCode(email,randomCode);
        return ResponseModel.getModel(ResultEnum.SUCCESS,null);
    }




    /**
     * emailRegister
     * @return
     * 手机端邮箱注册接口 (邮箱验证码)
     */
    @RequestMapping(value = "/emailRegister",method = RequestMethod.POST)
    @ResponseBody
    public Object emailRegister(@RequestBody JSONObject jsonObject){
        String code  = jsonObject.getString("code");
        String pid   = jsonObject.getString("pid");
        String email = jsonObject.getString("email");
        String password = jsonObject.getString("password");
        String sessionId = this.getSession().getId();

        if(Tools.isEmpty(code)){
            return ResponseModel.getModel(ResultEnum.CHECK_CODE_IS_EMPTY,null);
        }

        if(Tools.isEmpty(pid)){
            return ResponseModel.getModel(ResultEnum.PID_EMPTY_ERROR,null);
        }

        if(Tools.isEmpty(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_EMPTY_ERROR,null);
        }

        if(!Tools.isEmail(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_FORMAT_ERROR,null);
        }

        if(Tools.isEmpty(password)){
            return ResponseModel.getModel(ResultEnum.PASSWORD_IS_EMPTY,null);
        }

        if(password.length()<6){
            return ResponseModel.getModel(ResultEnum.PASSWORD_LENGTH_ERROR,null);
        }

       boolean flagpid = uaaService.isPidExist(pid);
        if(!flagpid){
            return ResponseModel.getModel(ResultEnum.PID_IS_NOT_EXIST_ERROR,null);
        }

        if(uaaService.isUserExist(email,pid)){
            return ResponseModel.getModel(ResultEnum.USERNAME_IS_EXIST, null);
        }

        boolean flagcheckCode = uaaService.checkRegisterEmailCode(code,email,pid,sessionId);
        if(!flagcheckCode){
            return ResponseModel.getModel(ResultEnum.VERIFY_CODE_IS_NOT_MATCH,null);
        }

        this.getSession().invalidate();
        ParameterMap parameterMap = new ParameterMap();
        parameterMap.put("password",password);
        parameterMap.put("username",email);
        parameterMap.put("pid",pid);
        parameterMap.put("sessionId",sessionId);
        parameterMap.put("code",code);
        parameterMap.put("type",1);
        parameterMap.put("email",email);
        return  uaaService.emailRegister(parameterMap);
    }

    /**
     * emailReset
     * @return
     * 手机端邮箱重置接口 (邮箱验证码)
     */
    @RequestMapping(value = "/emailReset",method = RequestMethod.POST)
    @ResponseBody
    public Object emailReset(@RequestBody JSONObject jsonObject){
        String code  = jsonObject.getString("code");
        String pid   = jsonObject.getString("pid");
        String email = jsonObject.getString("email");
        String password = jsonObject.getString("password");
        String sessionId = this.getSession().getId();

        if(Tools.isEmpty(code)){
            return ResponseModel.getModel(ResultEnum.CHECK_CODE_IS_EMPTY,null);
        }

        if(Tools.isEmpty(pid)){
            return ResponseModel.getModel(ResultEnum.PID_EMPTY_ERROR,null);
        }

        if(Tools.isEmpty(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_EMPTY_ERROR,null);
        }

        if(!Tools.isEmail(email)){
            return ResponseModel.getModel(ResultEnum.EMAILBOX_FORMAT_ERROR,null);
        }

        if(Tools.isEmpty(password)){
            return ResponseModel.getModel(ResultEnum.PASSWORD_IS_EMPTY,null);
        }

        if(password.length()<6){
            return ResponseModel.getModel(ResultEnum.PASSWORD_LENGTH_ERROR,null);
        }

        boolean flagpid = uaaService.isPidExist(pid);
        if(!flagpid){
            return ResponseModel.getModel(ResultEnum.PID_IS_NOT_EXIST_ERROR,null);
        }

        if(!uaaService.isUserExist(email,pid)){
            return ResponseModel.getModel(ResultEnum.USER_IS_NOT_EXIST, null);
        }

        boolean flagcheck = uaaService.checkResetEmailCode(code,email,pid,sessionId);
        if(!flagcheck){
            return ResponseModel.getModel(ResultEnum.VERIFY_CODE_IS_NOT_MATCH,null);
        }

        this.getSession().invalidate();
        ParameterMap parameterMap = new ParameterMap();
        parameterMap.put("password",password);
        parameterMap.put("username",email);
        parameterMap.put("pid",pid);
        parameterMap.put("sessionId",sessionId);
        parameterMap.put("code",code);
        parameterMap.put("type",2);
        parameterMap.put("email",email);
        return  uaaService.emailReset(parameterMap);
    }

    /**
     * oneKeyCreateAndLogin
     * @return
     * 手机端一键登录接口 (只需要客户端按一下就可以登录)
     */
    @RequestMapping(value = "/oneKeyCreateAndLogin",method = RequestMethod.POST)
    @ResponseBody
    public Object oneKeyCreateAndLogin(@RequestBody JSONObject jsonObject){


        String pid = jsonObject.getString("pid");
        String username = jsonObject.getString("username");
        String app_tid = jsonObject.getString("app_tid");
        long login_type = jsonObject.getLongValue("login_type");
        if(Tools.isEmpty(pid)){
            return ResponseModel.getModel(ResultEnum.PID_EMPTY_ERROR, null);
        }else if(Tools.isEmpty(username)){
            return ResponseModel.getModel(ResultEnum.USERNAME_IS_EMPTY, null);
        }else if(Tools.isEmpty(app_tid)){
            return ResponseModel.getModel(ResultEnum.PARAMS_EMPTY_ERROR, null);
        }
        else if(!Tools.isRegisterUserNameLegal(username)){
            return ResponseModel.getModel(ResultEnum.ILLEGAL_REGISTER, null);
        }
        else if(!jsonObject.containsKey("login_type") || (login_type!=0&&login_type!=1)){
            return ResponseModel.getModel(ResultEnum.PARAMETER_ERROR, null);
        }

        else {
            if(!uaaService.isPidExist(pid)){
                return ResponseModel.getModel(ResultEnum.PID_IS_NOT_EXIST_ERROR, null);
            }


                ParameterMap parameterMap = new ParameterMap();
                parameterMap.put("username",username);
                parameterMap.put("pid",pid);
                parameterMap.put("rip",this.getParameterMap().getString("rip"));
                parameterMap.put("app_tid",app_tid);
                parameterMap.put("expired_in",Const.ACCESS_TOKEN_EXPIRED_SECOND);
                return  uaaService.oneKeyCreateAndLogin(parameterMap);


        }
    }


    private String getrandom(){
        String code = "";
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            int r = random.nextInt(10); //每次随机出一个数字（0-9）
            code = code + r;  //把每次随机出的数字拼在一起
        }
        return code;

    }

}
